package com.inspur.edp.team.service.impl;

import com.inspur.edp.common.CommonConstants;
import com.inspur.edp.common.CommonUtils;
import com.inspur.edp.common.ParamValidation;
import com.inspur.edp.common.cache.CacheKeyConstants;
import com.inspur.edp.common.cache.DistCacheHelper;
import com.inspur.edp.paasuser.SynchronizationInfoService;
import com.inspur.edp.paasuser.dto.SynchqronizationInfoDto;
import com.inspur.edp.paasuser.service.impl.SynchronizationInfoServiceImpl;
import com.inspur.edp.team.PaasTeamMemberService;
import com.inspur.edp.team.converter.TeamMemberConverter;
import com.inspur.edp.team.dao.PaasEnvAuthorityDao;
import com.inspur.edp.team.dao.PaasTeamDao;
import com.inspur.edp.team.dao.PaasTeamMemberDao;
import com.inspur.edp.team.domain.PaasEnvAuthority;
import com.inspur.edp.team.domain.PaasTeam;
import com.inspur.edp.team.domain.PaasTeamMember;
import com.inspur.edp.team.domain.PaasTeamMemberCache;
import com.inspur.edp.team.dto.TeamMember;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.sysmanager.api.data.user.QueryMode;
import io.iec.edp.caf.sysmanager.api.data.user.User;
import io.iec.edp.caf.sysmanager.api.data.user.UserFilter;
import io.iec.edp.caf.sysmanager.api.data.user.UserPageData;
import io.iec.edp.caf.sysmanager.api.manager.user.UserManager;
import org.springframework.data.domain.Example;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 团队成员服务实现类
 */
public class PaasTeamMemberServiceImpl implements PaasTeamMemberService {

    private PaasTeamMemberDao paasTeamMemberDao = SpringBeanUtils.getBean(PaasTeamMemberDao.class);

    private TeamMemberConverter teamMemberConverter = SpringBeanUtils.getBean(TeamMemberConverter.class);

    private PaasTeamDao paasTeamDao = SpringBeanUtils.getBean(PaasTeamDao.class);

    private UserManager userManager = SpringBeanUtils.getBean(UserManager.class);

    private PaasEnvAuthorityDao paasEnvAuthorityDao = SpringBeanUtils.getBean(PaasEnvAuthorityDao.class);

    private SynchronizationInfoService synchronizationInfoService = new SynchronizationInfoServiceImpl();

    @Override
    public String addMember(String teamId, TeamMember teamMember) {
        try {
            // 参数校验
            if (Objects.isNull(teamMember)) {
                throw new RuntimeException("param can't null");
            }
            ParamValidation.checkParam(teamId, teamMember.getUserCode());

            // 越权校验
            User user = CommonUtils.findUserInfo();
            accessPermissioncheck(user.getId(), user.getName(), teamId);

            // 管理员校验
            editRoleCheck(user.getId(), user.getName(), teamId);

            Optional<PaasTeam> paasTeam = paasTeamDao.findById(teamId);
            if(!paasTeam.isPresent()){
                throw new RuntimeException("未获取到团队");
            }
            // 用户校验
            User addUser = userCheck(teamId, teamMember.getUserCode());

            // 自身校验
            if(user.getId().equals(addUser.getId())){
                throw new RuntimeException("管理员不能对自身进行操作");
            }

            // 重复性检查
            PaasTeamMember paasTeamMember = new PaasTeamMember()
                    .setYn(CommonConstants.YN_YES)
                    .setTeamId(teamId)
                    .setUserId(addUser.getId());
            List<PaasTeamMember> paasTeamMemberList = paasTeamMemberDao.findAll(Example.of(paasTeamMember));

            if(!CollectionUtils.isEmpty(paasTeamMemberList)){
                throw new RuntimeException("该用户已存在");
            }
            // 管理员角色修改校验
            for(PaasTeamMember ppt : paasTeamMemberList){
                if(ppt.getRoleType().equals(CommonConstants.TEAM_ROLE_ADMIN)){
                    throw new RuntimeException("用户以管理员角色存在，不可更改为非管理员");
                }
                else {
                    if(teamMember.getRoleType().equals(CommonConstants.TEAM_ROLE_ADMIN)){
                        throw new RuntimeException("用户以非管理员角色存在，不可更改为管理员");
                    }
                }
            }

            if(paasTeamMemberList.size()>1){
                throw new RuntimeException("id为"+teamId+"的团队下有多个重复用户");
            }
            if (CollectionUtils.isEmpty(paasTeamMemberList)) {
                // 构造团队成员对象
                paasTeamMember = genPaasTeamMember(teamId, addUser.getId(), user, teamMember.getRoleType());
                // 保存数据
                paasTeamMemberDao.save(paasTeamMember);
            } else {
                paasTeamMember = paasTeamMemberList.get(0);
                if ( Objects.nonNull(paasTeamMember.getRoleType()) && !paasTeamMember.getRoleType().equals(teamMember.getRoleType())) {
                    paasTeamMember.setRoleType(teamMember.getRoleType());
                    paasTeamMemberDao.save(paasTeamMember);
                }
            }
            //添加开发环境用户
            SynchqronizationInfoDto synchqronizationInfoDto = new SynchqronizationInfoDto()
                    .setTeamId(teamId)
                    .setUserId(teamMember.getUserId());
            if(teamMember.getRoleType() == 1) {
                synchqronizationInfoDto.setIsAdmin(true);
            }else{
                synchqronizationInfoDto.setIsAdmin(false);
            }
            synchronizationInfoService.addUser(synchqronizationInfoDto);
            // 清除团队成员缓存
            DistCacheHelper.getTeamSerializerInstance().evict(CacheKeyConstants.LCM_CACHE_APAAS_MEMBER + teamId);
            String teamName = paasTeam.get().getName();
            return "团队'" + teamName + "'中的用户" + addUser.getName() + "(" + addUser.getCode() + ")";
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("新增团队成员发生异常", e);
        }
    }

    @Override
    public void accessPermissioncheck(String userId, String userName, String teamId) {
        List<PaasTeamMember> paasTeamMemberList = getMemberUserByTeamId(teamId);
        Set<String> userIdSets = new HashSet<>();
        if (!CollectionUtils.isEmpty(paasTeamMemberList)) {
            userIdSets.addAll(paasTeamMemberList.stream().map(paasTeamMember -> paasTeamMember.getUserId()).collect(Collectors.toSet()));
        }
        if (!userIdSets.contains(userId) && !userId.equals("admin")) {
            throw new RuntimeException("用户不是该团队下成员");
        }
    }

    @Override
    public String removeMember(String teamId, String userId) {
        try {
            // 参数校验
            ParamValidation.checkParam(teamId, userId);

            // 越权校验
            User user = CommonUtils.findUserInfo();
            accessPermissioncheck(user.getId(), user.getName(), teamId);

            // 管理员校验
            editRoleCheck(user.getId(), user.getName(), teamId);

            Optional<PaasTeam> paasTeam = paasTeamDao.findById(teamId);
            if(!paasTeam.isPresent()){
                throw new RuntimeException("未获取到团队");
            }

            // 自身校验
            if(user.getId().equals(userId)){
                throw new RuntimeException("管理员不能对自身进行操作");
            }

            // 团队成员数不允许小于1
            businesscheck(user, teamId);

            // 移除团队成员
            PaasTeamMember paasTeamMember = new PaasTeamMember()
                    .setYn(CommonConstants.YN_YES)
                    .setUserId(userId)
                    .setTeamId(teamId);
            Optional<PaasTeamMember> paasTeamMemberForDel = paasTeamMemberDao.findOne(Example.of(paasTeamMember));
            if (!paasTeamMemberForDel.isPresent()) {
                throw new RuntimeException("该名成员已不存在");
            }
            User delUser = CommonUtils.findUserInfo(paasTeamMemberForDel.get().getUserId());
            paasTeamMemberDao.delete(paasTeamMemberForDel.get());
            removeMemberAuthority(teamId,paasTeamMemberForDel.get().getId());
            //禁用开发环境用户
            SynchqronizationInfoDto synchqronizationInfoDto = new SynchqronizationInfoDto()
                    .setTeamId(teamId)
                    .setUserId(userId)
                    .setUserSwitch(false);
            synchronizationInfoService.userSwitch(synchqronizationInfoDto);
            //团队名称
            String teamName = paasTeam.get().getName();
            // 清除团队成员缓存
            DistCacheHelper.getTeamSerializerInstance().evict(CacheKeyConstants.LCM_CACHE_APAAS_MEMBER + teamId);
            return Objects.nonNull(delUser) ? "团队'"+teamName+"'中的用户"+delUser.getName() + "(" + delUser.getCode() +
                    ")" : null;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("移除团队成员发生异常", e);
        }
    }

    @Override
    public String updateMember(TeamMember teamMember, String teamId){
        try {
        // 参数校验
        if (Objects.isNull(teamMember)) {
            throw new RuntimeException("param can't null");
        }
        ParamValidation.checkParam(teamId);

        // 越权校验
        User user = CommonUtils.findUserInfo();
        accessPermissioncheck(user.getId(), user.getName(), teamId);

        // 管理员校验
        editRoleCheck(user.getId(), user.getName(), teamId);

        Optional<PaasTeam> paasTeam = paasTeamDao.findById(teamId);
        if(!paasTeam.isPresent()){
            throw new RuntimeException("未获取到团队");
        }
        // 用户校验

        // 自身校验
        if(user.getId().equals(teamMember.getUserId())){
            throw new RuntimeException("管理员不能对自身进行操作");
        }
        Integer roleType = teamMember.getRoleType();
        if (roleType == null || roleType == -1) {
            throw new RuntimeException("请选择有效用户角色");
        }
        PaasTeamMember paasTeamMember = new PaasTeamMember()
                .setYn(CommonConstants.YN_YES)
                .setTeamId(teamId)
                .setUserId(teamMember.getUserId());
        List<PaasTeamMember> paasTeamMemberList = paasTeamMemberDao.findAll(Example.of(paasTeamMember));
        User updateUser = CommonUtils.findUserInfo(teamMember.getUserId());
        if(CollectionUtils.isEmpty(paasTeamMemberList)){
            throw new RuntimeException("该名成员已不存在");
        }
        paasTeamMember = paasTeamMemberList.get(0);
        if ( Objects.nonNull(paasTeamMember.getRoleType()) && !paasTeamMember.getRoleType().equals(teamMember.getRoleType())) {
            paasTeamMember.setRoleType(teamMember.getRoleType());
            paasTeamMemberDao.save(paasTeamMember);
        }
        DistCacheHelper.getTeamSerializerInstance().evict(CacheKeyConstants.LCM_CACHE_APAAS_MEMBER + teamId);
        String teamName = paasTeam.get().getName();
        return "团队'" + teamName + "'中的用户" + updateUser.getName() + "(" + updateUser.getCode() + ")";
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("编辑团队成员发生异常", e);
        }
    }


    @Override
    public  List<TeamMember> getMemberListByTeamId(String teamId) {
        try {
            // 参数校验
            ParamValidation.checkParam(teamId);

            // 越权校验


            // 查看团队成员
            List<PaasTeamMember> memberList = getMemberUserByTeamId(teamId);
            List<TeamMember> teamMemberList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(memberList)) {
                List<PaasTeamMember> paasTeamMemberList = memberList.stream().sorted(Comparator.comparing(PaasTeamMember::getCreatedTime).reversed()).collect(Collectors.toList());
                List<String> userIdSets = paasTeamMemberList.stream().map(paasTeamMember1 -> paasTeamMember1.getUserId()).collect(Collectors.toList());
                Map<String, User> userId2UserMap = CommonUtils.getUsersByIds(userIdSets);
                paasTeamMemberList.forEach(paasTeamMember1 -> {
                    TeamMember teamMember = teamMemberConverter.convert2TeamMember(paasTeamMember1, userId2UserMap);
                    teamMemberList.add(teamMember);
                });
                return teamMemberList;
            }
            return null;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("获取团队成员列表发生异常", e);
        }
    }
    @Override
    public TeamMember getMemberByTeamId(String teamId){
        try {
            // 参数校验
            ParamValidation.checkParam(teamId);
            // 越权校验
            User user = CommonUtils.findUserInfo();
            accessPermissioncheck(user.getId(), user.getName(), teamId);

            PaasTeamMember paasTeamMember = new PaasTeamMember()
                    .setYn(CommonConstants.YN_YES)
                    .setUserId(user.getId())
                    .setTeamId(teamId);
            Optional<PaasTeamMember> paasTeamMemberOptional = paasTeamMemberDao.findOne(Example.of(paasTeamMember));
            if (!paasTeamMemberOptional.isPresent() && !user.getId().equals("admin")) {
                throw new RuntimeException("该名成员已不存在");
            }
            if (user.getId().equals("admin")) {
                TeamMember teamMember = new TeamMember();
                teamMember.setUserId(user.getId());
                teamMember.setRoleType(1);
                return teamMember;
            }else {
                PaasTeamMember paasTeamMemberResult = paasTeamMemberOptional.get();
                TeamMember teamMember = new TeamMember();
                teamMember.setUserId(paasTeamMemberResult.getUserId());
                teamMember.setRoleType(paasTeamMemberResult.getRoleType());
                return teamMember;
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("获取团队成员发生异常", e);
        }

    }

    @Override
    public List<TeamMember> getMemberByUserId(String userId) {
        try {
            PaasTeamMember memberQuery = new PaasTeamMember();
            memberQuery.setUserId(userId);
            memberQuery.setYn(CommonConstants.YN_YES);
            List<PaasTeamMember> paasTeamMemberList = paasTeamMemberDao.findAll(Example.of(memberQuery));
            if (!CollectionUtils.isEmpty(paasTeamMemberList)) {
                return teamMemberConverter.toTargetList(paasTeamMemberList, TeamMember.class);
            }
            return null;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("查询成员归属的所有团队信息", e);
        }
    }

    @Override
    public List<TeamMember> getAll() {
        try {
            PaasTeamMember memberQuery = new PaasTeamMember();
            memberQuery.setYn(CommonConstants.YN_YES);
            List<PaasTeamMember> paasTeamMemberList = paasTeamMemberDao.findAll(Example.of(memberQuery));
            if (!CollectionUtils.isEmpty(paasTeamMemberList)) {
                return teamMemberConverter.toTargetList(paasTeamMemberList, TeamMember.class);
            }
            return null;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("查询所有团队信息" , e);
        }
    }


    /**
     * 用户有效性
     *
     * @param userCode
     * @return
     */
    private User userCheck(String teamId, String userCode) {
        // 获取当前用户
        List<String> codes = new ArrayList<>();
        codes.add(userCode);
        Map<String, User> userCode2UserMap = CommonUtils.getUsersByCodes(codes);
        User user = userCode2UserMap.get(userCode);
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户不存在！");
        }
        return user;
    }

    /**
     * 构造团队成员对象
     *
     * @param teamId
     * @param user
     * @return
     */
    private PaasTeamMember genPaasTeamMember(String teamId, String userId, User user, int roleType) {
        Timestamp time = Timestamp.valueOf(LocalDateTime.now());
        PaasTeamMember paasTeamMember = new PaasTeamMember()
                .setId(UUID.randomUUID().toString())
                .setTeamId(teamId)
                .setUserId(userId)
                .setRoleType(roleType)
                .setCreator(user.getName())
                .setCreatedTime(time)
                .setLastModifier(user.getName())
                .setLastModifiedTime(time)
                .setYn(CommonConstants.YN_YES);
        return paasTeamMember;
    }

    /**
     * 团队品下的成员数不准少于1
     *
     * @param user
     * @param teamId
     */
    private void businesscheck(User user, String teamId) {
        PaasTeamMember paasTeamMember = new PaasTeamMember()
                .setYn(CommonConstants.YN_YES)
                .setTeamId(teamId);
        List<PaasTeamMember> paasTeamMemberList = paasTeamMemberDao.findAll(Example.of(paasTeamMember));
        if (CollectionUtils.isEmpty(paasTeamMemberList) || paasTeamMemberList.size() < 2) {
            throw new RuntimeException("该团队下的成员数不准少于1");
        }
    }

    /**
     * 根据团队id查询成员信息
     *
     * @param teamId
     */
    private List<PaasTeamMember> getMemberUserByTeamId(String teamId) {
        if (Objects.isNull(teamId)) {
            return null;
        }
        PaasTeamMember paasTeamMemberQuery = new PaasTeamMember()
                .setYn(CommonConstants.YN_YES)
                .setTeamId(teamId);
        List<PaasTeamMember> result = paasTeamMemberDao.findAll(Example.of(paasTeamMemberQuery));
        if (!CollectionUtils.isEmpty(result)) {
            DistCacheHelper.getTeamSerializerInstance()
                    .put(CacheKeyConstants.LCM_CACHE_APAAS_MEMBER + teamId, new PaasTeamMemberCache().setPaasTeamMemberList(result));
        }
        return result;
    }

    /**
     * 根据用户ID和团队ID校验用户是否为管理员
     * @param userId
     * @param userName
     * @param teamId
     */
    public void editRoleCheck(String userId, String userName, String teamId){
        PaasTeamMember paasTeamMemberQuery = new PaasTeamMember()
                .setYn(CommonConstants.YN_YES)
                .setTeamId(teamId)
                .setUserId(userId);

        List<PaasTeamMember> result = paasTeamMemberDao.findAll(Example.of(paasTeamMemberQuery));

        for(PaasTeamMember member : result){
            if(!member.getRoleType().equals(CommonConstants.TEAM_ROLE_ADMIN) && !userId.equals("admin")){
                throw new RuntimeException("用户不是该团队下管理员");
            }
        }
    }

    /**
     * 邀请用户-用户名过滤查询
     * @param userStr
     * @return
     */
    @Override
    public List<User> checkUserRes(String userStr) {
        if (org.springframework.util.StringUtils.isEmpty(userStr)) {
            return new ArrayList<>();
        }

        //获取igix用户名集合
        UserFilter filter = new UserFilter();
        filter.setQueryMode(QueryMode.UserList);
        filter.setCodeOrName(userStr);
        UserPageData usersByFilter = userManager.getUsersByFilter(filter);
        List<User> localUser = usersByFilter.getData();
        return localUser;
    }
    public void accessPermissioncheck(String teamId) {
        User user = CommonUtils.findUserInfo();
        List<PaasTeamMember> paasTeamMemberList = getMemberUserByTeamId(teamId);
        Set<String> userIdSets = new HashSet<>();
        if (!CollectionUtils.isEmpty(paasTeamMemberList)) {
            userIdSets.addAll(paasTeamMemberList.stream().map(paasTeamMember -> paasTeamMember.getUserId()).collect(Collectors.toSet()));
        }
        if (!userIdSets.contains(user.getId()) && !user.getId().equals("admin")) {
            throw new RuntimeException("用户不是该团队下成员");
        }
    }
    public void removeMemberAuthority(String teamId, String memberId){
        try{
            ParamValidation.checkParam(teamId,memberId);
            PaasEnvAuthority paasEnvAuthorityQuery = new PaasEnvAuthority()
                    .setTeamid(teamId)
                    .setMemberid(memberId);
            List<PaasEnvAuthority> paasEnvAuthoritylist = paasEnvAuthorityDao.findAll(Example.of(paasEnvAuthorityQuery));
            if(!CollectionUtils.isEmpty(paasEnvAuthoritylist)){
                for(PaasEnvAuthority paasEnvAuthority : paasEnvAuthoritylist){
                    paasEnvAuthorityDao.delete(paasEnvAuthority);
                }
            }
        }catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("移除成员环境权限发生异常", e);
        }
    }

}
